paint-brush
GRASP क्या है? जावास्क्रिप्ट में सूचना विशेषज्ञ और निर्माता सिद्धांतद्वारा@serhiirubets
11,880 रीडिंग
11,880 रीडिंग

GRASP क्या है? जावास्क्रिप्ट में सूचना विशेषज्ञ और निर्माता सिद्धांत

द्वारा Serhii Rubets1m2022/06/07
Read on Terminal Reader
Read this story w/o Javascript

बहुत लंबा; पढ़ने के लिए

GRASP को *सामान्य उत्तरदायित्व उत्तरदायित्व असाइनमेंट सॉफ़्टवेयर पैटर्न के रूप में संक्षिप्त किया गया है। यह सिफारिशों, सिद्धांतों और पैटर्न का एक सेट है जो वास्तव में अच्छा है और हमारे कोड को बहुत बेहतर बना सकता है। आज हमारे पास कई सर्वोत्तम अभ्यास, सिद्धांत (SOLID, DRY, GoF, KISS, और अन्य) और अन्य हैं, और वे सभी हमारी मदद करने, अच्छा, रखरखाव योग्य कोड और समझने योग्य कोड लिखने की कोशिश कर रहे हैं। हम कार्यक्षमता बनाना चाहते हैं, जो हमारे आदेशित वस्तुओं की कुल राशि की गणना करेगी। हम पहले 2 सिद्धांत सीखेंगे: सूचना विशेषज्ञ और निर्माता।

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - GRASP क्या है? जावास्क्रिप्ट में सूचना विशेषज्ञ और निर्माता सिद्धांत
Serhii Rubets HackerNoon profile picture

आज, हमारे पास कई अच्छे अभ्यास, सिद्धांत (SOLID, DRY, KISS), GoF पैटर्न और बहुत कुछ हैं।

वे सभी हमारी मदद करने की कोशिश कर रहे हैं, डेवलपर्स, अच्छा, स्वच्छ, रखरखाव योग्य और समझने योग्य कोड लिखें।


GRASP सामान्य उत्तरदायित्व असाइनमेंट सॉफ़्टवेयर पैटर्न का संक्षिप्त नाम है।


यह सिफारिशों, सिद्धांतों और पैटर्न का एक सेट है जो वास्तव में अच्छा है और हमारे कोड को और बेहतर बना सकता है। आइए एक नजर डालते हैं इस लिस्ट पर:


  • सूचना विशेषज्ञ
  • बनाने वाला
  • नियंत्रक
  • कम युग्मन
  • उच्च सामंजस्य
  • शुद्ध निर्माण
  • अविवेक
  • संरक्षित विविधताएं
  • बहुरूपता


आज, हम पहले 2 सिद्धांत सीखेंगे: सूचना विशेषज्ञ और निर्माता।

सूचना विशेषज्ञ

सभी GRASP पैटर्न में सूचना विशेषज्ञ सबसे महत्वपूर्ण हो सकता है। यह पैटर्न कहता है कि डेटा (चर, फ़ील्ड) के साथ काम करने वाली सभी विधियाँ उसी स्थान पर होनी चाहिए जहाँ डेटा (चर या फ़ील्ड) मौजूद हों।


मुझे पता है, मुझे पता है, यह इतना स्पष्ट नहीं है, तो चलिए एक उदाहरण देखते हैं। हम ऐसी कार्यक्षमता बनाना चाहते हैं जो हमारे ऑर्डर की गई वस्तुओं की कुल राशि की गणना करे।


आइए कल्पना करें कि हमारे पास 4 फाइलें हैं: main.js, OrderList, OrderItem, और Product।


उत्पाद में आईडी, नाम और मूल्य (और कई अन्य फ़ील्ड, जो हमारे उदाहरण से संबंधित नहीं हैं) हो सकते हैं:


 class Product { constructor(name, price) { this.name = name; this.price = price; } }


ऑर्डरइटम एक साधारण वस्तु होगी जिसमें उत्पाद और गिनती शामिल है, जैसे नीचे:


 class OrderItem { constructor(product, count) { this.product = product, this.count = count } }


ऑर्डरलिस्ट फ़ाइल में ऑर्डर इटम्स की एक सरणी के साथ काम करने के लिए तर्क होगा।


 class OrderList { constructor(items) { this.items = items; } }


और, main.js केवल वह फ़ाइल है जिसमें कुछ प्रारंभिक तर्क हो सकते हैं, ऑर्डरलिस्ट आयात कर सकते हैं, और इस सूची के साथ कुछ कर सकते हैं।


 import { OrderItem } from './OrderItem'; import { OrderList } from './OrderList'; import { Product } from './Product'; const samsung = new Product('Samsung', 200); const apple = new Product('Apple', 300); const lg = new Product('Lg', 150); const samsungOrder = new OrderItem(samsung, 2); const appleOrder = new OrderItem(samsung, 3); const lgOrder = new OrderItem(samsung, 4); const orderList = new OrderList([samsungOrder, appleOrder, lgOrder]);


कुल योग की गणना करने वाली विधि कहाँ बनाई जानी चाहिए? कम से कम 2 फाइलें हैं, और उनमें से प्रत्येक हम इस उद्देश्य के लिए उपयोग कर सकते हैं, है ना? लेकिन हमारे लक्ष्य के लिए कौन सी जगह बेहतर होगी?


आइए main.js के बारे में सोचें।


हम कुछ इस तरह लिख सकते हैं:


 const totalSum = orderList.reduce((res, order) => { return res + order.product.price * order.count }, 0)


यह काम करेगा। लेकिन, ऑर्डरइटम फ़ाइल में विधियों के बिना डेटा होता है, ऑर्डरलिस्ट फ़ाइल में विधि के बिना डेटा भी होता है, और मुख्य फ़ाइल में एक विधि होती है जो ऑर्डर आइटम और ऑर्डर सूची के साथ काम करती है।


यह अच्छा नहीं लगता। यदि हम और अधिक तर्क जोड़ना चाहते हैं जो किसी तरह आदेशों के साथ काम करता है, तो क्या हम इसे मुख्य फ़ाइल में भी रखेंगे? और, कुछ समय बाद, हमारी मुख्य फाइल में हजारों कोड लाइनों के लिए बहुत सारे अलग-अलग तर्क होंगे, जो वास्तव में खराब है। इस एंटीपैटर्न को गॉड ऑब्जेक्ट कहा जाता है, जहां 1 फाइल में सब कुछ होता है।


यदि हम सूचना विशेषज्ञ दृष्टिकोण का उपयोग करना चाहते हैं तो यह कैसा होना चाहिए? आइए दोहराने की कोशिश करें:


डेटा (चर, फ़ील्ड) के साथ काम करने वाली सभी विधियाँ उसी स्थान पर होनी चाहिए जहाँ डेटा (चर या फ़ील्ड) मौजूद हों।


इसका अर्थ है: ऑर्डरइटम में तर्क होना चाहिए जो किसी विशिष्ट आइटम के लिए योग की गणना कर सकता है:


 class OrderItem { constructor(product, count) { this.product = product, this.count = count } getTotalPrice() { return this.product.price * this.count; } }


और ऑर्डरलिस्ट में तर्क होना चाहिए जो सभी ऑर्डर आइटम के लिए कुल योग की गणना कर सके:


 class OrderList { constructor(items) { this.items = items; } getTotalPrice() { return this.items.reduce((res, item) => { return res + item.getTotalPrice(); }, 0); } }


और, हमारी मुख्य फ़ाइल सरल होगी और उसमें उस कार्यक्षमता के लिए तर्क नहीं होगा; यह यथासंभव सरल होगा (कई आयातों को छोड़कर, जिन्हें हम जल्द ही हटा देंगे)।


तो, कोई भी तर्क, जो केवल एक ऑर्डर आइटम के सापेक्ष है, को ऑर्डर करने के लिए रखा जाना चाहिए।

अगर कुछ ऑर्डर के सेट के साथ अपेक्षाकृत काम कर रहा है, तो हमें उस तर्क को ऑर्डर में रखना चाहिए।


हमारी मुख्य फ़ाइल केवल एक प्रवेश बिंदु होनी चाहिए; कुछ तैयारी करें, और आयात करें, और कुछ तर्क को दूसरों के साथ जोड़ें।


यह अलगाव हमें कोड घटकों के बीच बहुत कम निर्भरता देता है, और यही कारण है कि हमारा कोड बहुत अधिक रखरखाव योग्य है।


हम हमेशा इस सिद्धांत का उपयोग अपनी परियोजना में नहीं कर सकते हैं, लेकिन यह वास्तव में एक अच्छा सिद्धांत है। और यदि आप इसका उपयोग कर सकते हैं, तो आपको इसे करना चाहिए।

बनाने वाला

हमारे पिछले उदाहरण में, हमारे पास 4 फाइलें थीं: मुख्य, ऑर्डरलिस्ट, ऑर्डरइटम, और उत्पाद। सूचना विशेषज्ञ का कहना है कि विधियां कहां होनी चाहिए: उसी स्थान पर जहां डेटा है।


लेकिन सवाल यह है कि वस्तुओं को कौन और कहां बनाया जाना चाहिए? ऑर्डरलिस्ट कौन बनाएगा, ऑर्डरआइटम कौन बनाएगा, उत्पाद कौन बनाएगा?


निर्माता का कहना है कि प्रत्येक वस्तु (वर्ग) को उसी स्थान पर बनाया जाना चाहिए जहां उसका उपयोग किया जाएगा। कई आयातों के साथ मुख्य फ़ाइल में हमारा उदाहरण याद रखें? चलो देखते है:


 import { OrderItem } from './OrderItem'; import { OrderList } from './OrderList'; import { Product } from './Product'; const samsung = new Product('Samsung', 200); const apple = new Product('Apple', 300); const lg = new Product('Lg', 150); const samsungOrder = new OrderItem(samsung, 2); const appleOrder = new OrderItem(samsung, 3); const lgOrder = new OrderItem(samsung, 4); const orderList = new OrderList([samsungOrder, appleOrder, lgOrder]); const totalSum = orderList.getTotalPrice();


जैसा कि हम देख सकते हैं, लगभग सभी आयात और वस्तु निर्माण main.js में हैं।


लेकिन, आइए इस बारे में सोचें कि इसका वास्तव में कौन और कहां उपयोग किया जाता है।


उत्पाद केवल ऑर्डरइटम में उपयोग किया जाता है। ऑर्डरइटम केवल ऑर्डरलिस्ट में उपयोग किया जाता है। ऑर्डरलिस्ट का उपयोग मेन पर किया जाता है। यह इस तरह दिख रहा है:


मुख्य → ऑर्डरलिस्ट → ऑर्डरइटम → प्रोडक्ट


लेकिन अगर मुख्य केवल ऑर्डरलिस्ट का उपयोग करता है, तो हम ऑर्डरइटम को मेन में क्यों बनाते हैं? हम यहां एक उत्पाद भी क्यों बनाते हैं? इस समय के लिए, हमारा Main.js लगभग सब कुछ बनाता है (और आयात करता है)। यह बुरा है।


सृष्टिकर्ता सिद्धांत का पालन करते हुए, हमें वस्तुओं को केवल उन्हीं जगहों पर बनाना चाहिए जहाँ इन वस्तुओं का उपयोग किया जाता है। कल्पना कीजिए कि, हमारे ऐप का उपयोग करके, हमने कार्ट में उत्पादों को जोड़ा। यह ऐसा दिख सकता है:


Main.js: हम यहां केवल ऑर्डरलिस्ट बनाते हैं (और आयात करते हैं):


 import { OrderList } from './OrderList'; const cartProducts = [{ name: 'Samsung', price: 200, count: 2 }, { name: 'Apple', price: 300, count: 3 }, {name: 'Lg', price: 150, count: 4 }]; const orderList = new OrderList(cartProducts); const totalPrice = orderList.getTotalPrice();


ऑर्डरलिस्ट.जेएस: हम यहां केवल ऑर्डरइटम बनाते हैं (और आयात करते हैं):


 import { OrderItem } from './OrderItem'; class OrderList { constructor(items) { this.items = items.map(item => new OrderItem(item)); } getTotalPrice() { return this.items.reduce((res, item) => { return res + item.getPrice(); }, 0); } }


OrderItem.js: हम यहां केवल उत्पाद बनाते हैं (और आयात करते हैं):


 import { Product } from './Product'; class OrderItem { constructor(item) { this.product = new Product(item.name, item.price); this.count = item.count; } }


उत्पाद.जेएस:


 class Product { constructor(name, price) { this.name = name; this.price = price; } }


हमारे पास एक साधारण निर्भरता है:


मुख्य → ऑर्डरलिस्ट → ऑर्डरइटम → उत्पाद


और अब, प्रत्येक वस्तु केवल उसी स्थान पर निर्मित होती है, जहां उसका उपयोग किया जाता है। सृष्टिकर्ता सिद्धांत यही कहता है।


मुझे आशा है कि यह परिचय आपके लिए उपयोगी होगा, और GRASP की अगली श्रृंखला में, हम अन्य सिद्धांतों को शामिल करेंगे।


Unsplash . पर गेब्रियल हेनज़र द्वारा फोटो